from datetime import datetime
from django.shortcuts import render, redirect, HttpResponse
from rest_framework import viewsets, status
from rest_framework.response import Response
from rest_framework.permissions import IsAuthenticated
from rest_framework.authentication import SessionAuthentication
from rest_framework import mixins
from rest_framework.views import APIView

from rest_framework_jwt.authentication import JSONWebTokenAuthentication

from .permissions import IsOwnerOrReadOnly
from .models import ShoppingCart, OrderInfo, OrderGoods
from .serializers import ShopCartSerializer, ShopCartDetailSerializer, OrderSerializer, OrderDetailSerializer
from WorkBookShop.utils.al_pay import alipay


class ShoppingCartViewset(viewsets.ModelViewSet):
    """
    购物车功能
    list:
        获取购物车详情
    create：
        加入购物车
    delete：
        删除购物记录
    """
    permission_classes = (IsAuthenticated, IsOwnerOrReadOnly)
    authentication_classes = (JSONWebTokenAuthentication, SessionAuthentication)
    serializer_class = ShopCartSerializer
    lookup_field = "goods_id"

    def create(self, request, *args, **kwargs):
        print(request.data)
        serializer = self.get_serializer(data=request.data)
        serializer.is_valid(raise_exception=True)
        self.perform_create(serializer)
        headers = self.get_success_headers(serializer.data)
        return Response(serializer.data, status=status.HTTP_201_CREATED, headers=headers)

    # 库存数-1
    def perform_create(self, serializer):
        shop_cart = serializer.save()
        goods = shop_cart.goods
        goods.goods_num -= shop_cart.nums
        goods.save()

    # 库存数+1
    def perform_destroy(self, instance):
        goods = instance.goods
        goods.goods_num += instance.nums
        goods.save()
        # 取goods在del之前取之后就被删掉了
        instance.delete()

    # 更新库存
    def perform_update(self, serializer):
        existed_record = ShoppingCart.objects.get(id=serializer.instance.id)
        existed_nums = existed_record.nums
        # 先保存之前的数据existed_nums
        saved_record = serializer.save()
        # 变化的数量
        nums = saved_record.nums - existed_nums
        goods = saved_record.goods
        goods.goods_num -= nums
        goods.save()

    def get_serializer_class(self):
        if self.action == 'list':
            return ShopCartDetailSerializer
        else:
            return ShopCartSerializer

    def get_queryset(self):
        return ShoppingCart.objects.filter(user=self.request.user)


class OrderViewset(mixins.ListModelMixin, mixins.RetrieveModelMixin, mixins.CreateModelMixin, mixins.DestroyModelMixin,
                   viewsets.GenericViewSet):
    """
    订单管理
    list:
        获取个人订单
    delete:
        删除订单
    create：
        新增订单
    """
    permission_classes = (IsAuthenticated, IsOwnerOrReadOnly)
    authentication_classes = (JSONWebTokenAuthentication, SessionAuthentication)
    serializer_class = OrderSerializer

    def get_queryset(self):
        return OrderInfo.objects.filter(user=self.request.user)

    def get_serializer_class(self):
        if self.action == "retrieve":
            return OrderDetailSerializer
        return OrderSerializer

    def create(self, request, *args, **kwargs):  # 这个为后添加context={'request': request} 为什么有没有这个，在Serializer都能拿到request对象？
        serializer = self.get_serializer(data=request.data, context={'request': request})
        serializer.is_valid(raise_exception=True)
        self.perform_create(serializer)
        headers = self.get_success_headers(serializer.data)
        return Response(serializer.data, status=status.HTTP_201_CREATED, headers=headers)

    def destroy_handle(self, existed_orders):
        """
        删除为付款订单时把库存数回复
        """
        # 拿到所有该订单相关的商品列表
        order_goods = existed_orders.goods.all()
        # 商品销量增加订单中数值
        for order_good in order_goods:
            goods = order_good.goods
            goods.goods_num += order_good.goods_num  # 库存数+上取消订单里商品的数
            goods.save()

    def destroy(self, request, *args, **kwargs):
        # 如果订单没有交易成功，就在库存+1并删除订单；如果交易成功就直接删除订单
        url = request.get_full_path()  # /orders/17/
        order_id = url.split('/')[-2]

        existed_orders = OrderInfo.objects.filter(id=order_id).first()
        if existed_orders.pay_status == 'paying':  # 如果状态为paying则添加库存
            self.destroy_handle(existed_orders)

        instance = self.get_object()
        self.perform_destroy(instance)
        return Response(status=status.HTTP_204_NO_CONTENT)

    def perform_create(self, serializer):
        order = serializer.save()
        # 获取到用户购物车里的商品，并把商品订单保存到数据库
        shop_carts = ShoppingCart.objects.filter(user=self.request.user)
        for shop_cart in shop_carts:
            order_goods = OrderGoods()
            order_goods.goods = shop_cart.goods
            order_goods.goods_num = shop_cart.nums
            order_goods.order = order
            order_goods.save()
            shop_cart.delete()  # 删除购物车的商品
        # return order


class AlipayView(APIView):

    def get(self, request):
        """
        处理支付宝的return_url返回
        """
        # 前端发来查询数据库订单是否支付成功
        # trade_no = request.query_params.get('out_trade_no')
        # order = OrderInfo.objects.filter(order_sn=trade_no).first()
        # if order.pay_status == 'TRADE_SUCCESS':
        #     # 如果订单状态为TRADE_SUCCESS返回支付成功
        #     return HttpResponse('支付成功')
        # else:
        #     return HttpResponse('支付失败')

        data = request.query_params.dict()
        signature = data.pop("sign")

        # verification
        success = alipay.verify(data, signature)
        # if success and data["trade_status"] in ("TRADE_SUCCESS", "TRADE_FINISHED"):
        if success:
            self.success(data)
            return Response('支付成功')
        else:
            return Response('支付失败')

    def success(self, data):
        """
        验证签成功后才能执行
        """
        # 这里最好记个订单收款日志(未记)

        order_sn = data.get('out_trade_no', None)  # 本系统订单号
        trade_no = data.get('trade_no', None)  # 支付宝流水号
        timestamp = data.get('timestamp', None)  # 支付时间
        # 查询数据库中存在的订单
        # 根据订单号查询订单查询
        existed_orders = OrderInfo.objects.filter(order_sn=order_sn).first()
        # 拿到所有该订单相关的商品列表
        order_goods = existed_orders.goods.all()
        # 商品销量增加订单中数值
        for order_good in order_goods:
            goods = order_good.goods
            goods.sold_num += order_good.goods_num
            goods.save()

        # 更新订单状态，填充支付宝给的交易凭证号。
        existed_orders.pay_status = 'TRADE_SUCCESS'
        existed_orders.trade_no = trade_no
        existed_orders.pay_time = datetime.now()
        existed_orders.save()

    def post(self, request):
        """
        此方法只能在有公网ip后才会有回调请求
        处理支付宝的notify_url
        即支付完成后支付宝发送的成功回调post请求
        必须先验证支付宝发来的签名，正确后去修改订单状态
        """

        data = request.data.dict()
        from WorkBookShop.utils.logger import log
        log.error(data)
        trade_no = data.get('trade_no', None)
        timestamp = data.get('timestamp', None)  # 支付时间

        signature = data.pop("sign")

        # verification
        success = alipay.verify(data, signature)
        if success and data["trade_status"] in ("TRADE_SUCCESS", "TRADE_FINISHED"):
            OrderInfo.objects.filter(trade_no=trade_no).update(pay_status='TRADE_SUCCESS', pay_time=timestamp)
            self.success(data)
            # 将success返回给支付宝，支付宝就不会一直不停的继续发消息了。
            return Response("success")
        else:
            return Response('error')
